'use strict';

var validators = module.exports = {};

var debug = require('debug'),
  log = debug('yozh:lib:log'),
  error = debug('yozh:lib:error'),
  verbose = debug('yozh:lib:verbose'),
  uuid = require('uuid'),
  respData = require('../config/json_resp_data'),
  tools = require('./tools');

validators.check = function(context, checkArray, sourceName) {
  sourceName = sourceName || '';
  if (typeof(context) !== 'object') {
    // var errorId = uuid.v4();
    var errors = respData.createErrors(
      // errorId,
      500,
      '00001',
      '对象错误',
      sourceName
    );
    return errors;
  }
  var params = {};
  switch(context.method) {
    case 'GET':
      params = context.query;
      break;
    case 'POST':
      params = context.request.body;
      break;
    case 'PUT':
      // es6
      Object.assign(params, context.params, context.request.body);
      break;
    case 'DELETE':
      params = context.params;
      break;
  }
  // log(params);
  /*if (tools.isEmptyObject(params)) {
    var errorId = uuid.v4();
    var errors = respData.createErrors(
      errorId,
      400,
      '01002',
      '缺少参数',
      sourceName,
      {
        method: req.method,
        path: req.path
      }
    );
    return errors;
  }*/
  // log('checkArray is Array? ', Array.isArray(checkArray));
  if (!Array.isArray(checkArray)) {
    checkArray = [checkArray];
  }
  for (var i = 0; i < checkArray.length; i ++) {
    // obj: {'param': [{ checkFun: 'check', errStatus: 'status',
    // errCode: 'code', errDetail: 'detail', errSource: 'source'}]}
    var obj = checkArray[i];
    for (var key in obj) {
      // log('key:', key);
      // The body of a for in should be wrapped in an if statement
      // to filter unwanted properties from the prototype
      if (obj) {
        var checkList = obj[key];
        // verbose(checkList);
        for (var j = 0; j < checkList.length; j ++) {
          var item = checkList[j];
          if (item.checkFun) {
            var validate = validators[item.checkFun](params[key]);
            log('check function: ', item.checkFun,
              key, ': ', params[key],
              'validators.check: ', validate);
            if (!validate) {
              // var perrorId = uuid.v4();
              var status = item.errStatus || 400;
              var code = item.errCode || '01002';
              var detail = item.errDetail || '';
              var source = item.errSource || sourceName || '';
              var perrors = respData.createErrors(
                // perrorId,
                status,
                code,
                detail,
                source,
                {
                  method: context.request.method,
                  path: context.request.path
                }
              );
              return perrors;
            }
          }
        }
      }
    }
  }
  return null;
};

/**
 * require
 * @param  {Number|String|Object} val value
 * @return {Boolean}     true|false
 */
validators.need = function(val) {
  if (!val) {
    return false;
  }
  return true;
};

/**
 * isDigit: is number
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isDigit = function(val) {
  var pattern = /^[0-9]{1,20}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * isUsername: start with a-zA-Z, length between 5-20
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isUsername = function(val) {
  var pattern = /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * use a-zA-Z and length between 1-30
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isTrueName = function(val) {
  var pattern = /^[a-zA-Z]{1,30}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * all of word and length between 6-20
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isPassword = function(val) {
  var pattern = /^(\w){6,20}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * telephone
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isTel = function(val) {
  var pattern = /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * mobil
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isMobil = function(val) {
  var pattern = /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * postal code
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isPostalCode = function(val) {
  var pattern = /^[a-zA-Z0-9 ]{3,12}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * ip address
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isIP = function(val) {
  var pattern = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * chinese
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isChinese = function(val) {
  var pattern = /^[\u4e00-\u9fa5] {0,}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * email
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isEmail = function(val) {
  var pattern = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * url
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isUrl = function(val) {
  var pattern = /(http[s]?|ftp):\/\/[^\/\.]+?\..+\w$/i;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * Special characters
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isUnkown = function(val) {
  var pattern = /[@#\$%\^&\*]+/g;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};

/**
 * Special characters
 * @param  {Number|String}  val value
 * @return {Boolean} true|false
 */
validators.isSearch = function(val) {
  var pattern = /^[^`~!@#$%^&*()+=|\\\][\]\{\}:;\'\,.<>\/?]{1}[^`~!@$%^&()+=|\\\][\]\{\}:;\'\,.<>?]{0,19}$/;
  if (!pattern.exec(val)) {
    return false;
  }
  return true;
};
